package com.qcby.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qcby.admin.config.SystemConstants;
import com.qcby.admin.form.AddArticleForm;
import com.qcby.admin.form.ArticleForm;
import com.qcby.admin.model.SgArticle;
import com.qcby.admin.dao.SgArticleMapper;

import com.qcby.admin.model.SgArticleTag;
import com.qcby.admin.model.SgCategory;
import com.qcby.admin.service.SgArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcby.admin.service.SgArticleTagService;
import com.qcby.admin.service.SgCategoryService;
import com.qcby.admin.vo.*;
import com.qcby.framwork.utils.BeanCopyUtils;
import com.qcby.framwork.utils.ResponseResult;
import javafx.scene.chart.Chart;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2024-09-08
 */
@Service
public class SgArticleServiceImpl extends ServiceImpl<SgArticleMapper, SgArticle> implements SgArticleService {
    @Autowired
    private SgArticleService sgArticleService;
    @Autowired
    private SgArticleMapper sgArticleMapper;
    @Autowired
    private SgCategoryService sgCategoryService;
    @Autowired
    private SgArticleTagService sgArticleTagService;

    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        LambdaQueryWrapper<SgArticle> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        //判空。如果前端传了categoryId这个参数，那么查询时要和传入的相同。第二个参数是数据表的文章id，第三个字段是前端传来的文章id
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId) && categoryId > 0, SgArticle::getCategoryId, categoryId);

        //只查询状态是正式发布的文章。Article实体类的status字段跟0作比较，一样就表示是正式发布的
        lambdaQueryWrapper.eq(SgArticle::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);

        //对isTop字段进行降序排序，实现置顶的文章(isTop值为1)在最前面
        lambdaQueryWrapper.orderByDesc(SgArticle::getIsTop);

        //分页查询
        Page<SgArticle> page = new Page<>(pageNum, pageSize);
        page(page, lambdaQueryWrapper);
        //用categoryId来查询categoryName(category表的name字段)，也就是查询'分类名称'
        List<SgArticle> articles = page.getRecords();

        articles.stream()
                .map(new Function<SgArticle, SgArticle>() {
                    @Override
                    public SgArticle apply(SgArticle article) {
                        //'article.getCategoryId()'表示从article表获取category_id字段，然后作为查询category表的name字段
                        SgCategory category = sgCategoryService.getById(article.getCategoryId());
                        String name = category.getName();
                        //把查询出来的category表的name字段值，也就是article，设置给Article实体类的categoryName成员变量
                        article.setCategoryName(name);
                        //把查询出来的category表的name字段值，也就是article，设置给Article实体类的categoryName成员变量
                        return article;
                    }
                })
                .collect(Collectors.toList());
        List<ArticleListVO> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVO.class);
        PageVo pageVo = new PageVo(articleListVos, (int) page.getTotal());
        return ResponseResult.okResult(pageVo);

    }

    @Override
    public ResponseResult getArticleDetail(Long id) {
        //根据id查询文章
        SgArticle sgArticle = getById(id);
        //转换成id
        ArticleDetailVO articleDetailVo = com.qcby.framwork.utils.BeanCopyUtils.copyBean(sgArticle, ArticleDetailVO.class);
        //根据分类id查询分类名
        Long catehoryId = articleDetailVo.getCategoryId();
        SgCategory sgCategory = sgCategoryService.getById(catehoryId);
        if (sgArticle != null) {
            articleDetailVo.setCategoryName(sgCategory.getName());
        }
        //封装响应返回
        return ResponseResult.okResult(articleDetailVo);
    }

    @Override
    public ResponseResult updateViewCount(Long id) {
        return null;
    }

    @Override
    @Transactional
    public ResponseResult add(AddArticleForm articleDto) {
        //添加 博客
        SgArticle article = BeanCopyUtils.copyBean(articleDto, SgArticle.class);
        save(article);


        List<SgArticleTag> articleTags = articleDto.getTags().stream()
                .map(tagId -> new SgArticleTag(article.getId(), tagId))
                .collect(Collectors.toList());

        //添加 博客和标签的关联
        sgArticleTagService.saveBatch(articleTags);
        return ResponseResult.okResult();
    }
    @Override
    public PageVo selectArticlePage(SgArticle sgArticle, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<SgArticle> queryWrapper = new LambdaQueryWrapper();

        queryWrapper.like(StringUtils.hasText(sgArticle.getTitle()),SgArticle::getTitle, sgArticle.getTitle());
        queryWrapper.like(StringUtils.hasText(sgArticle.getSummary()),SgArticle::getSummary, sgArticle.getSummary());

        Page<SgArticle> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page(page,queryWrapper);

        //转换成VO
        List<SgArticle> articles = page.getRecords();

        //这里偷懒没写VO的转换 应该转换完在设置到最后的pageVo中

        PageVo pageVo = new PageVo();
        pageVo.setTotal((int) page.getTotal());
        pageVo.setRows(articles);
        return pageVo;
    }

    //回显
    @Override
    public ArticleVo getInfo(Long id) {
        SgArticle article = getById(id);
        //获取关联标签
        LambdaQueryWrapper<SgArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleTagLambdaQueryWrapper.eq(SgArticleTag::getArticleId,article.getId());
        List<SgArticleTag> articleTags = sgArticleTagService.list(articleTagLambdaQueryWrapper);
        List<Long> tags = articleTags.stream().map(articleTag -> articleTag.getTagId()).collect(Collectors.toList());

        ArticleVo articleVo = BeanCopyUtils.copyBean(article,ArticleVo.class);
        articleVo.setTags(tags);
        return articleVo;
    }

    //修改
    @Override
    public void edit(ArticleForm articleForm) {
        SgArticle article = BeanCopyUtils.copyBean(articleForm, SgArticle.class);
        //更新博客信息
        updateById(article);
        //删除原有的 标签和博客的关联
        LambdaQueryWrapper<SgArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleTagLambdaQueryWrapper.eq(SgArticleTag::getArticleId,article.getId());
        sgArticleTagService.remove(articleTagLambdaQueryWrapper);
        //添加新的博客和标签的关联信息
        List<SgArticleTag> articleTags = articleForm.getTags().stream()
                .map(tagId -> new SgArticleTag(articleForm.getId(), tagId))
                .collect(Collectors.toList());
        sgArticleTagService.saveBatch(articleTags);
    }
    //热门文章数量统计
    @Override
    public HotArticleVO hotcount() {
        HotArticleVO hotArticleVO = new HotArticleVO();
        //查询前十文章名字
        QueryWrapper<SgArticle> sgArticleQueryWrapper = new QueryWrapper<>();
        sgArticleQueryWrapper.orderByDesc("view_count")
                .last("LIMIT 5"); //限制十条
        // 执行查询
        List<SgArticle> topArticles = sgArticleService.list(sgArticleQueryWrapper);
        //复制标题字段
        List<String> articles = new ArrayList<>();
        //复制访问量字段
        List<Long> visits = new ArrayList<>();
        for (SgArticle article: topArticles
        ) {
            articles.add(article.getTitle());
            visits.add(article.getViewCount());
        }
        //封装字段
        hotArticleVO.setArticles(articles);
        hotArticleVO.setVisits(visits);


        return hotArticleVO;
    }
    //文章类别统计
    @Override
    public List<Map<String, String>> categorycount() {
        List<Map<String,String>> categoryMapVos = new ArrayList<>();
        //查询到 value name
        List<NameValueVo> nameValueVos = sgArticleMapper.categoryValue();
        //数据导入
        for (NameValueVo nv: nameValueVos
        ) {
            Map<String,String> map = new HashMap<>();
            map.put(nv.getValue().toString(), nv.getName());
            categoryMapVos.add(map);
        }
        return categoryMapVos;
    }
    //文章用户统计
    @Override
    public List<Map<String, String>> usercount() {
        List<Map<String,String>> userMapVos = new ArrayList<>();
        //查询到 value name
        List<NameValueVo> nameValueVos = sgArticleMapper.userValue();
        //数据导入
        for (NameValueVo nv: nameValueVos
        ) {
            Map<String,String> map = new HashMap<>();
            map.put(nv.getValue().toString(), nv.getName());
            userMapVos.add(map);
        }
        return userMapVos;
    }
}